////////////////////////////////////////////////////////////////
//
//       Filename:  InterIO.go
//
//        Version:  1.0
//        Created:  2022年11月07日 12时08分53秒
//       Revision:  none
//       Compiler:  go
//
//         Author:  alpha
//   Organization:  alpha
//       Contacts:  chenxinquan@kylinos.com
//
////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////
// Description:
////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////
// Log:
////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////
// Todo:
//
////////////////////////////////////////////////////////////////

package Interpreter

import (
    "bufio"
    "bytes"
    "strings"
    "os/exec"
)

////////////////////////////////////////////////////////////////
// InterIO struct
type
InterIO struct {
    Reader *bufio.Reader
    Writer *bufio.Writer
    Cmd    *exec.Cmd
}

///////////////////////////////
// InterIO functions
func
(iio InterIO) Send(str string) (rc error) {
    _, rc = iio.Writer.WriteString(str)
    iio.Writer.Flush()
    /* */
    return rc
}

func
(iio InterIO) Sendline(str string) (rc error) {
    _, rc = iio.Writer.WriteString(str + "\n")
    iio.Writer.Flush()
    /* */
    return rc
}

func
(iio InterIO) RecvUntil(delim_s string) (ret string, rc error) {
    output := ""
    /* */
    for {
        recv, err := iio.Reader.ReadBytes(delim_s[len(delim_s) - 1])
        /* */
        if (nil != err) {
            return "", err
        } // if ( ...

        output += string(recv)

        // 针对单个字符或字符较少的delim_s
        if ( ( len(recv) >= len(delim_s)                     ) &&
             ( bytes.Equal(recv[len(recv) - len(delim_s):],
                           []byte(delim_s)                 ) )      ) {
            break
        } // if ( ( len ...

        // 针对字符较多的delim_s
        if strings.Contains(output, delim_s) {
            break
        }
    } // for { ...

    ret = output
    rc  = nil
    /* */
    return ret, rc
}

func
(iio InterIO) RecvUntilByte(delim_b byte) (string, error) {
    recv, rc := iio.Reader.ReadBytes(delim_b)
    /* */
    return string(recv), rc
}

func
(iio InterIO) RecvLine() (string, bool, error) {

    recv, isPrefix, rc := iio.Reader.ReadLine()

    return string(recv), isPrefix, rc
}

func
(iio InterIO) Recv(n int) (string, error) {
    var out []byte
    var rc error
    for i := 0; i < n ; i++ {
        c, rc1 := iio.Reader.ReadByte()

        out = append(out, c)
        rc = rc1
    }

    return string(out), rc
}

func
(iio InterIO) RecvString(delim byte) (line string, rc error) {
    line, rc = iio.Reader.ReadString(delim)

    return line, rc
}
